// decodetest.cpp
// Copyright (C) 2008 Sam Bateman
// samuel.bateman@gmail.com
//
// This file is part of DVD On Fire.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include <cerrno>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <error.h>
#include <string>
#include <sys/stat.h>
#include <tivodecode/tivodecoder.h>
using namespace std;

int o_verbose = 0;
int o_no_verify = 0;

// myfread(mem, size, fh) {{{
int myfread(void *mem, int size, void *fh)
{
    return fread(mem, 1, size, (FILE *)fh);
}
// }}}
// myfwrite(mem, size, fh) {{{
int myfwrite(void *mem, int size, void *fh)
{
    return fwrite(mem, 1, size, (FILE *)fh);
}
// }}}
// main(argc, argv) {{{
int main(int argc, char **argv)
{
    // check for command-line arguments
    if (argc < 2){
        printf("Usage: %s <tivo file>\n", argv[0]);
        return 1;
    }
    string input_file = argv[1];
    string output_file = "dtout.mpg";
    string mak = "4888337277";

    // start timing
    unsigned int start_time = time(NULL);

    // get the file size
    struct stat s;
    int r = stat(input_file.c_str(), &s);
    if (r != 0) error(1, errno, "Error with stat()");
    off_t size = s.st_size;

    // open the tivo files and create turing info
    FILE *fp_in = fopen(input_file.c_str(), "rb");
    FILE *fp_out = fopen(output_file.c_str(), "wb");
    if (!fp_in) error(1, errno, "Error with fopen()");
    turing_state turing;
    memset(&turing, 0, sizeof(turing));
    r = init_turing_from_file(&turing, fp_in, myfread, (char *)mak.c_str());
    if (r == -1) error(1, 0, "Error with init_turing_from_file()");
    fseek(fp_in, r, SEEK_SET);

    // read and write mpeg frames
    unsigned int marker = 0xffffffff;
    unsigned char byte;
    bool first = true;
    while (true){
        if ((marker & 0xffffff00) == 0x100){
            off_t pos = ftello(fp_in);
            r = process_frame(byte, &turing, pos, fp_in, myfread,
                                  fp_out, myfwrite);
            if (r == 1) marker = 0xffffffff;
            else if (r == 0) fwrite(&byte, 1, 1, fp_out);
            else if (r < 0) error(1, 0, "Error with process_frame()");
            printf("\rProgress: % 10.6f%%",
                   (double)pos / size * 100);
            fflush(stdout);
        }
        else if (!first){
            fwrite(&byte, 1, 1, fp_out);
        }
        marker <<= 8;
        if (fread(&byte, 1, 1, fp_in) != 0){
            marker |= byte;
        }
        else {
            break;
        }
        first = false;
    }
    printf("\rProgress: 100.000000%%\n");

    // end timing
    unsigned int end_time = time(NULL);
    int time_taken = end_time - start_time;
    printf("Time taken: %dh %dm %ds\n",
           time_taken / 3600, time_taken / 60 % 60, time_taken % 60);

    // clean up
    destruct_turing(&turing);
    fclose(fp_in);
    fclose(fp_out);
}
// }}}
